#ifndef _SEQ_PARAM_SET_H_
#define _SEQ_PARAM_SET_H_

#include <stdint.h>
#include <vector>

//Based on https://www.itu.int/rec/T-REC-H.264-201402-S/en

typedef struct
{
    //int   Valid;                  // indicates the parameter set is valid
    unsigned int profile_idc;                                       // u(8)
    int   constrained_set0_flag;                                // u(1)
    int   constrained_set1_flag;                                // u(1)
    int   constrained_set2_flag;                                // u(1)
    int   constrained_set3_flag;                                // u(1)
    int   constrained_set4_flag;                                // u(1)
    int   constrained_set5_flag;                                // u(1)
    int   reserved_zero_2bits;                                        //u(2)

    unsigned  int level_idc;                                        // u(8)
    unsigned  int seq_parameter_set_id;                             // ue(v)

    unsigned  int chroma_format_idc;                                // ue(v)

    int separate_colour_plane_flag;                          //u(1)

    int bit_depth_luma_minus8;                                // ue(v)
    int bit_depth_chroma_minus8;                               // ue(v)
    int qpprime_y_zero_transform_bypass_flag;                  //u(1)


    int   seq_scaling_matrix_present_flag;                   // u(1)
    int   seq_scaling_list_present_flag;                 // u(1)
    //int       ScalingList4x4[6][16];                             // se(v)
    //int       ScalingList8x8[6][64];                             // se(v)
    //int   UseDefaultScalingMatrix4x4Flag[6];
    //int   UseDefaultScalingMatrix8x8Flag[6];

    unsigned int log2_max_frame_num_minus4;                        // ue(v)
    unsigned int pic_order_cnt_type;
    // if( pic_order_cnt_type == 0 )
    unsigned int log2_max_pic_order_cnt_lsb_minus4;                 // ue(v)
    // else if( pic_order_cnt_type == 1 )
    int delta_pic_order_always_zero_flag;               // u(1)
    int     offset_for_non_ref_pic;                         // se(v)
    int     offset_for_top_to_bottom_field;                 // se(v)
    unsigned int num_ref_frames_in_pic_order_cnt_cycle;          // ue(v)
    // for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
    //int   offset_for_ref_frame[256];   // se(v)
    unsigned int num_ref_frames;                                   // ue(v)
    int   gaps_in_frame_num_value_allowed_flag;             // u(1)

    unsigned int pic_width_in_mbs_minus1;                          // ue(v)
    unsigned int pic_height_in_map_units_minus1;                   // ue(v)
    int   frame_mbs_only_flag;                              // u(1)
    // if( !frame_mbs_only_flag )
    int   mb_adaptive_frame_field_flag;                   // u(1)
    int   direct_8x8_inference_flag;                        // u(1)
    int   frame_cropping_flag;                              // u(1)
    unsigned int frame_crop_left_offset;                // ue(v)
    unsigned int frame_crop_right_offset;               // ue(v)
    unsigned int frame_crop_top_offset;                 // ue(v)
    unsigned int frame_crop_bottom_offset;              // ue(v)
    int   vui_parameters_present_flag;                      // u(1)
    //vui_seq_parameters_t vui_seq_parameters;                  // vui_seq_parameters_t
    //unsigned  separate_colour_plane_flag;                       // u(1)

    /* vui_parameters */
    struct
    {
        uint8_t aspect_ration_info_present_flag;

        /* aspect_ration_info_present_flag == 1 */
        uint8_t aspect_ratio_idc;
        uint16_t sar_width;
        uint16_t sar_height;

        uint8_t overscan_info_present_flag;
        /* overscan_info_present_flag == 1 */
        uint8_t overscan_appropriate_flag;

        uint8_t video_signal_type_present_flag;
        /* video_signal_type_present_flag == 1 */
        uint8_t video_format;
        uint8_t video_full_range_flag;
        uint8_t colour_description_present;
        /* colour_description_present == 1 */
        uint8_t colour_primaries;
        uint8_t transfer_characteristics;
        uint8_t matrix_coefficients;

        uint8_t chroma_loc_info_present_flag;
        /* chroma_loc_info_present_flag == 1 */
        uint8_t chroma_sample_loc_type_top_field;
        uint8_t chroma_sample_loc_type_bottom_field;

        uint8_t timing_info_present_flag;
        /* timing_info_present_flag == 1 */
        uint32_t num_units_in_tick;
        uint32_t time_scale;
        uint8_t fixed_frame_rate_flag;

        uint8_t nal_hrd_parameters_present_flag;
        struct hrd_parameters nal_hrd_parameters;

        uint8_t vc1_hrd_parameters_present_flag;
        struct hrd_parameters vc1_hrd_parameters;

        uint8_t low_delay_hrd_flag;

        uint8_t pic_struct_present_flag;
        uint8_t bitstream_restriction_flag;

        /* bitstream_restriction_flag == 1 */
        uint8_t motion_vectors_over_pic_boundaries;
        uint32_t max_bytes_per_pic_denom;
        uint32_t max_bits_per_mb_denom;
        uint32_t log2_max_mv_length_horizontal;
        uint32_t log2_max_mv_length_vertical;
        uint32_t num_reorder_frames;
        uint32_t max_dec_frame_buffering;
    } vui_parameters;
} seq_parameter_set_rbsp;


class CSeqParamSet
{
public:
    CSeqParamSet(const uint8_t* data, uint32_t size);
    CSeqParamSet(std::vector<uint8_t>& data);
    ~CSeqParamSet();

    //Open API..
    void  Dump_sps_info();


private:

    seq_parameter_set_rbsp sps;

    const uint8_t* m_data;
    uint32_t m_size;

    uint32_t m_height;
    uint32_t m_width;


};

#endif

